package service

import (
	"encoding/json"
	"fmt"
	"html"
	"io/ioutil"
	"net/http"
	"regexp"
	"strings"
)

type SongInfo struct {
	Code int `json:"code"`
	Data struct {
		Album struct {
			Curnum   int           `json:"curnum"`
			Curpage  int           `json:"curpage"`
			List     []interface{} `json:"list"`
			Totalnum int           `json:"totalnum"`
		} `json:"album"`
		Keyword string `json:"keyword"`
		Mv      struct {
			Curnum   int           `json:"curnum"`
			Curpage  int           `json:"curpage"`
			List     []interface{} `json:"list"`
			Totalnum int           `json:"totalnum"`
		} `json:"mv"`
		Priority int           `json:"priority"`
		Qc       []interface{} `json:"qc"`
		Sematic  struct {
			Curnum   int           `json:"curnum"`
			Curpage  int           `json:"curpage"`
			List     []interface{} `json:"list"`
			Totalnum int           `json:"totalnum"`
		} `json:"sematic"`
		Song struct {
			Curnum  int `json:"curnum"`
			Curpage int `json:"curpage"`
			List    []struct {
				AlbumNameHilight string `json:"albumName_hilight"`
				Chinesesinger    int    `json:"chinesesinger"`
				Docid            string `json:"docid"`
				F                string `json:"f"`
				Fiurl            string `json:"fiurl"`
				Fnote            int    `json:"fnote"`
				Fsinger          string `json:"fsinger"`
				Fsinger2         string `json:"fsinger2"`
				Fsong            string `json:"fsong"`
				Grp              []struct {
					AlbumNameHilight   string `json:"albumName_hilight"`
					Chinesesinger      int    `json:"chinesesinger"`
					Docid              string `json:"docid"`
					F                  string `json:"f"`
					Fiurl              string `json:"fiurl"`
					Fnote              int    `json:"fnote"`
					Fsinger            string `json:"fsinger"`
					Fsinger2           string `json:"fsinger2"`
					Fsong              string `json:"fsong"`
					Isupload           int    `json:"isupload"`
					Isweiyun           int    `json:"isweiyun"`
					Lyric              string `json:"lyric"`
					LyricHilight       string `json:"lyric_hilight"`
					Mv                 string `json:"mv"`
					Nt                 int64  `json:"nt"`
					Only               int    `json:"only"`
					PubTime            int    `json:"pubTime"`
					Pure               int    `json:"pure"`
					SingerMID          string `json:"singerMID"`
					SingerMID2         string `json:"singerMID2"`
					SingerName2Hilight string `json:"singerName2_hilight"`
					SingerNameHilight  string `json:"singerName_hilight"`
					Singerid           int    `json:"singerid"`
					Singerid2          int    `json:"singerid2"`
					SongNameHilight    string `json:"songName_hilight"`
					T                  int    `json:"t"`
					Tag                int    `json:"tag"`
					Ver                int    `json:"ver"`
				} `json:"grp"`
				Isupload           int    `json:"isupload"`
				Isweiyun           int    `json:"isweiyun"`
				Lyric              string `json:"lyric"`
				LyricHilight       string `json:"lyric_hilight"`
				Mv                 string `json:"mv"`
				Nt                 int64  `json:"nt"`
				Only               int    `json:"only"`
				PubTime            int    `json:"pubTime"`
				Pure               int    `json:"pure"`
				SingerMID          string `json:"singerMID"`
				SingerMID2         string `json:"singerMID2"`
				SingerName2Hilight string `json:"singerName2_hilight"`
				SingerNameHilight  string `json:"singerName_hilight"`
				Singerid           int    `json:"singerid"`
				Singerid2          int    `json:"singerid2"`
				SongNameHilight    string `json:"songName_hilight"`
				T                  int    `json:"t"`
				Tag                int    `json:"tag"`
				Ver                int    `json:"ver"`
			} `json:"list"`
			Totalnum int `json:"totalnum"`
		} `json:"song"`
		Totaltime float64 `json:"totaltime"`
		Zhida     struct {
			Chinesesinger int `json:"chinesesinger"`
			Type          int `json:"type"`
		} `json:"zhida"`
	} `json:"data"`
	Message string `json:"message"`
	Notice  string `json:"notice"`
	Subcode int    `json:"subcode"`
	Time    int    `json:"time"`
	Tips    string `json:"tips"`
}

type Song struct {
	Lyric     string
	AlbumName string
	Singer    string
}
type Lyric struct {
	Retcode int    `json:"retcode"`
	Code    int    `json:"code"`
	Subcode int    `json:"subcode"`
	Type    int    `json:"type"`
	Songt   int    `json:"songt"`
	Lyric   string `json:"lyric"`
}

func GetSongInfo(singer, songName, ossName string) (song Song) {
	resp, _ := http.Get("https://c.y.qq.com/soso/fcgi-bin/music_search_new_platform?searchid=53806572956004615&t=1&aggr=1&cr=1&catZhida=1&lossless=0&flag_qc=0&p=1&n=10&w=" + songName)
	defer resp.Body.Close()
	by, _ := ioutil.ReadAll(resp.Body)
	re := regexp.MustCompile(`callback|\(|\)`)
	res := re.ReplaceAll(by, []byte(""))
	songInfo := SongInfo{}
	json.Unmarshal(res, &songInfo)
	song.Singer = singer
	for _, s := range songInfo.Data.Song.List {
		if s.Fsinger == singer {
			f := s.F
			info := strings.Split(f, "|")
			GetSongImg(info[22], ossName)
			song.Lyric = GetSongLyric(info[0])
			song.AlbumName = s.AlbumNameHilight
			break
		}
	}
	return
}

func GetSongImg(albumid, ossName string) {
	url := fmt.Sprintf("https://y.gtimg.cn/music/photo_new/T002R300x300M000%s_1.jpg", albumid)
	resp, _ := http.Get(url)
	ext, contentType := GetContentType(url)
	if resp.ContentLength > 0 {
		file := FileIO{
			ObjectName:  ossName + "." + ext,
			FileReader:  resp.Body,
			BucketName:  ext,
			ContentType: contentType,
			Size:        resp.ContentLength,
			Type:        0,
		}
		FileUploadChan <- file
	}
}
func GetSongLyric(lyric string) string {
	url := fmt.Sprintf("https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_yqq.fcg?nobase64=1&musicid=%s&-=jsonp1&g_tk_new_20200303=5381&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8&notice=0&platform=yqq.json&needNewCode=0", lyric)
	client := &http.Client{}
	request, _ := http.NewRequest("GET", url, nil)
	request.Header.Add("referer", "https://y.qq.com/n/yqq/song/003OUlho2HcRHC.html")
	resp, _ := client.Do(request)
	defer resp.Body.Close()
	bodyBytes, _ := ioutil.ReadAll(resp.Body)
	var res Lyric
	json.Unmarshal(bodyBytes, &res)
	//reader := bytes.NewReader(bodyBytes)
	//decoder := xml.NewDecoder(reader)
	//decoder.CharsetReader = charset.NewReaderLabel
	//var ly string
	//decoder.Decode(&ly)
	return html.UnescapeString(res.Lyric)
}
